// 18.6 泛型程序设计（Generic Programming）
// 泛型程序设计是 C++ 模板的核心应用，它允许我们编写能够适用于多种类型的代码，同时保持类型安全和高性能。下面我将详细解释泛型程序设计的概念、原则和实践。

// --------------------------------------------------------------
// 泛型程序设计的核心概念
// 泛型程序设计的核心思想是将算法与数据类型分离，使算法能够适用于各种满足特定要求的类型。在 C++ 中，这主要通过模板实现。

// --------------------------------------------------------------
// 基本原则
// 1.抽象：关注类型的行为而非具体类型
// 2.参数化：通过模板参数替代具体类型
// 3.概念（Concepts）：定义类型必须满足的要求
// 4.效率：生成的代码应该与手写的专用代码一样高效


// --------------------------------------------------------------
// 泛型程序设计的实现方式
// 1. 基于接口的泛型
// 这是最基本的泛型形式，要求类型提供特定的接口（方法或操作）：
template<typename T>
T max(T a, T b) {
    return a < b ? b : a;  // 要求 T 支持 < 操作符
}


// 2. 基于概念的泛型（C++20）
// C++20 引入了概念（Concepts），使泛型约束更加明确：
template<typename T>
concept Sortable = requires(T& a) {
    { std::begin(a) } -> std::input_iterator;
    { std::end(a) } -> std::input_iterator;
    requires std::totally_ordered<std::iter_value_t<decltype(std::begin(a))>>;
};

template<Sortable T>
void sort(T& container) {
    // 实现排序算法
}

// 3.3. 特性类（Traits）
// 特性类是泛型程序设计中的重要工具，用于获取或修改类型特性：
// 迭代器特性类
template<typename Iterator>
struct iterator_traits {
    using value_type = typename Iterator::value_type;
    using difference_type = typename Iterator::difference_type;
    using pointer = typename Iterator::pointer;
    using reference = typename Iterator::reference;
    using iterator_category = typename Iterator::iterator_category;
};

// 针对指针的特化
template<typename T>
struct iterator_traits<T*> {
    using value_type = T;
    using difference_type = std::ptrdiff_t;
    using pointer = T*;
    using reference = T&;
    using iterator_category = std::random_access_iterator_tag;
};

// -----------------------------------------------------------
// 泛型程序设计的实例：STL
// 标准模板库（STL）是泛型程序设计的典范，它包括：
// 1. 容器（Containers）
// 泛型容器可以存储任何类型的元素：
std::vector<int> numbers;
std::map<std::string, double> prices;

// 2. 算法（Algorithms）
// 泛型算法可以操作任何满足要求的容器：
std::vector<int> v = {5, 2, 8, 1, 3};
std::sort(v.begin(), v.end());  // 排序任何支持随机访问的容器

// 3. 迭代器（Iterators）
// 迭代器是连接容器和算法的桥梁：
template<typename InputIt, typename T>
InputIt find(InputIt first, InputIt last, const T& value) {
    for (; first != last; ++first) {
        if (*first == value) {
            return first;
        }
    }
    return last;
}

// ---------------------
// 泛型程序设计的优势
1.代码复用：一次编写，适用于多种类型
2.类型安全：在编译期检查类型错误
3.高性能：生成的代码与手写的专用代码一样高效
4.表达力：可以表达复杂的算法和数据结构关系

// 泛型程序设计的挑战
1.错误消息复杂：模板错误消息往往难以理解
2.编译时间增加：模板实例化会增加编译时间
3.代码膨胀：为每种类型生成独立代码可能导致可执行文件变大
4.接口设计难度：设计好的泛型接口需要深入理解问题领域

// 泛型程序设计的最佳实践
1.关注概念而非类型：定义类型必须满足的要求
2.最小化约束：只要求必要的操作和类型
3.提供默认实现：为常见情况提供优化的实现
4.文档化要求：明确说明类型必须满足的条件

// 总结
泛型程序设计是 C++ 中强大的编程范式，它通过模板实现代码复用和类型安全。理解泛型编程的原则和技术，可以帮助我们编写更灵活、更高效的代码。随着 C++20 概念的引入，泛型程序设计变得更加强大和易用，为 C++ 开发带来了新的可能性。
